package com.rongke.sms;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 功能:  web.wasun.cn HTTP接口 发送短信
 * 说明:	  http://web.wasun.cn/asmx/smsservice.aspx?name=登录名&pwd=接口密码&mobile=手机号码&content=内容&sign=签名&stime=发送时间&type=pt&extno=自定义扩展码
 */
@Service
@Transactional
public class SmsService {
    private Logger log = Logger.getLogger(this.getClass());

    /**
     * @param type
     * @throws IOException
     */
    public SmsTemplate.SmsContentCode smsCodeByType(String mobile, Integer type) {
        //发送内容
        SmsTemplate.SmsContentCode templateCode = SmsTemplate.getTemplateCode(type);
        assert templateCode != null;
        String sign = templateCode.getSing();


        // 创建StringBuffer对象用来操作字符串
        StringBuilder sb = new StringBuilder("http://web.wasun.cn/asmx/smsservice.aspx?");

        // 向StringBuffer追加用户名
        try {
            sb.append("name=").append(URLEncoder.encode(SmsTemplate.NAME, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // 向StringBuffer追加密码（登陆网页版，在管理中心--基本资料--接口密码，是28位的）
        sb.append("&pwd=").append(SmsTemplate.PWD);

        // 向StringBuffer追加手机号码
        sb.append("&mobile=").append(mobile);

        // 向StringBuffer追加消息内容转URL标准码
        try {
            sb.append("&content=").append(URLEncoder.encode(templateCode.getContent(), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        //追加发送时间，可为空，为空为及时发送
        sb.append("&stime=");

        //加签名
        if (sign != null) {
            try {
                sb.append("&sign=").append(URLEncoder.encode(sign, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {
            try {
                sb.append("&sign=").append(URLEncoder.encode("", "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        //type为固定值pt  extno为扩展码，必须为数字 可为空
        sb.append("&type=pt&extno=");
        // 创建url对象
        //String temp = new String(sb.toString().getBytes("GBK"),"UTF-8");
        System.out.println("sb:" + sb.toString());
        URL url = null;
        try {
            url = new URL(sb.toString());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        // 打开url连接
        HttpURLConnection connection = null;
        try {
            assert url != null;
            connection = (HttpURLConnection) url.openConnection();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 设置url请求方式 ‘get’ 或者 ‘post’
        try {
            assert connection != null;
            connection.setRequestMethod("POST");
        } catch (ProtocolException e) {
            e.printStackTrace();
        }

        // 发送
        InputStream is = null;
        try {
            is = url.openStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        //转换返回值
        String returnStr = convertStreamToString(is);

        // 返回结果为‘0，20140009090990,1，提交成功’ 发送成功   具体见说明文档
        System.out.println(returnStr);
        if (!returnStr.contains("提交成功")) {
            try {
                throw new Exception(returnStr);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 返回发送结果
        return templateCode;
    }

    /**
     * 转换返回值类型为UTF-8格式.
     *
     * @param is
     * @return
     */
    private static String convertStreamToString(InputStream is) {
        StringBuilder sb1 = new StringBuilder();
        byte[] bytes = new byte[4096];
        int size = 0;

        try {
            while ((size = is.read(bytes)) > 0) {
                String str = new String(bytes, 0, size, "UTF-8");
                sb1.append(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb1.toString();
    }

    /**
     * 短信模板
     */
    public static class SmsTemplate {
        static final String NAME = "15957400831";
        static final String PWD = "9FA6EB4D075A98F84F896CF0D451";
        /**
         * 模板内容
         */
        private static final Map<Integer, String> TEMPLATE_MAP = new HashMap<>();

        static {
            TEMPLATE_MAP.put(1, "您好，您的验证码为[??]，请注意保管。【及时雨】");
            TEMPLATE_MAP.put(2, "您好，您的验证码为[??]，请注意保管。【及时雨】");

        }

        /**
         * 获取模板替换占位
         *
         * @param type 类型
         */
        static SmsContentCode getTemplateCode(Integer type) {
            String template;
            if (type == 3) {
                //自定义短信模板
                template = SmsTempletEnum.getSmsTempletNameByType(1).getTypeName();
                SmsContentCode smsContentCode = new SmsContentCode();
                smsContentCode.setContent(template);
                return smsContentCode;
            } else {
                template = TEMPLATE_MAP.get(type);
                if (StringUtils.isBlank(template)) {
                    return null;
                }

                SmsContentCode smsContentCode = new SmsContentCode();
                if (template.contains("[??]") && template.contains("【")) {
                    String random = randomString(4);
                    smsContentCode.setCode(random);
                    String sing = template.split("【")[1].split("】")[0];
                    smsContentCode.setSing(sing);
                    template = template.replace("[??]", random + "").split("【")[0];
                }
                smsContentCode.setContent(template);
                return smsContentCode;
            }
        }

        /**
         * 获取count个随机数
         *
         * @param count 随机数个数
         * @return 随机数
         */
        private static String randomString(int count) {
            StringBuilder sb = new StringBuilder();
            String str = "0123456789";
            Random r = new Random();
            for (int i = 0; i < count; i++) {
                int num = r.nextInt(str.length());
                sb.append(str.charAt(num));
                str = str.replace((str.charAt(num) + ""), "");
            }
            return sb.toString();
        }

        /**
         * 短信内容和验证码
         */
        public static class SmsContentCode {
            /**
             * 短信内容
             */
            private String content;
            /**
             * 验证码
             */
            private String code;
            /**
             * 签名
             */
            private String sing;

            public String getContent() {
                return content;
            }

            public void setContent(String content) {
                this.content = content;
            }

            public String getCode() {
                return code;
            }

            public void setCode(String code) {
                this.code = code;
            }

            public String getSing() {
                return sing;
            }

            void setSing(String sing) {
                this.sing = sing;
            }
        }

    }

}
